import com.sun.xml.internal.ws.api.model.wsdl.WSDLOutput;

import java.util.ArrayList;
import java.util.Random;
import java.util.Scanner;

import static sun.security.jgss.GSSUtil.login;

/*
ATM系统入口类
 */
public class ATMSystem {
    public static void main(String[] args) {
        //1.定义账户类
        //  2.定义一个集合容器 负责存储全部的账户对象 进行相关的业务操作
        ArrayList<Account> accounts=new ArrayList<>();
        Scanner sc=new Scanner(System.in);
        //3.展示系统的首页
        while (true) {
            System.out.println("===============达内ATM系统=================");
            System.out.println("1.账户登录");
            System.out.println("2.账户注册");
            System.out.println("请你选择操作");
            int command=sc.nextInt();

            switch (command){
                case 1:
                    //用户登录操作
                    login(accounts,sc);
                    break;
                case 2:
                    //用户注册操作(alt+回车)
                    register(accounts,sc);
                    break;
                default:
                    System.out.println("你输入的命令不存在！");
            }
        }

    }

    /**
     *登录功能
     * @param accounts 全部账户对象的集合
     * @param sc  扫描器
     *
     */
    private static void login(ArrayList<Account> accounts, Scanner sc) {
        System.out.println("==========系统登录操作=========");
        //1.判断账户集合中是否存在账户 如何不存在 登录功能不能进行
        if (accounts.size()==0){
            System.out.println("对不起！你当前系统中无任何账户 请先开户再来登录 ");
            return;//w为语言风格 结束当前方法
        }

        //2、正式进入登录操作
        while (true) {
            System.out.println("请你输入登录卡号");
            String cardId=sc.next();
            //判断卡号是否存在 根据卡号 去账户集合 中查询账户登录

            Account     acc= getAccountByCardId(cardId,  accounts) ;
            if (acc!=null){
    //            卡号存在
                while (true) {
                    //4.让用户输入密码 认证密码
                    System.out.println("请你输入登录密码");
                    String passWord=sc.next();
                    //判断当前账户对象密码是否与用户输入 密码一致
                    if (acc.getPassWord().equals(passWord)){
                            //登录成功
                        System.out.println("恭喜你"+acc.getUserName()+"先生/女士进入系统,你的卡号是"+acc.getCardId());
                        //查询 转账 取款
                        //展示登录后的操作业
                        showUserCommand(sc,acc,accounts);
                        return;//干掉登录方法
                    }else{
                        System.out.println("对不起 你输入的密码有误");
                    }
                }
            }else{
                System.out.println("对不起 系统中不存在该账户卡号  ！");
            }
        }
    }
/*展示登录后的操作页

 */

    private static void showUserCommand(Scanner sc,Account acc,ArrayList<Account> accounts) {
        while (true) {
            System.out.println("========用户操作页========");
            System.out.println("1.查询账户");
            System.out.println("2.存款");
            System.out.println("3.取款");
            System.out.println("4.转账");
            System.out.println("5.修改密码");
            System.out.println("6.退出系统");
            System.out.println("7.注销账户");
            System.out.println("请选择:");
            int command=sc.nextInt();
            switch (command){
                case 1:
                    //查询账户 展示当前登录账号信息
                    showAccount(acc);
                    break;
                case 2:
                    //存款
                    depositMone(acc,sc);
                    break;
                case 3:
                    //取款
                    drawMoney(acc,sc);
                    break;
                case 4:
                    //转账
                    transMoney(sc,acc,accounts);
                    break;
                case 5:

                    //修改密码
                    updatePassWord (sc,acc);
                    return;//
                case 6:
                    //退出
                    System.out.println("退出成功，欢迎下次光临");
                    return;//让当前方法停止
                case 7:
                    //注销
                    //从当前集合 删除当前账户对象 销户就完成了
                    deleAccount(acc,sc,accounts);
                    return;
                default:
                    System.out.println("你输入的操作命令不正确");



            }
        }

    }

    /**
     * 销户功
     * @param acc
     * @param sc  扫码器
     * @param accounts
     */
    private static void deleAccount(Account acc, Scanner sc, ArrayList<Account> accounts) {
        System.out.println("=====用户销户功能======");
        System.out.println("你真的要销户吗？x/y");
        String r=sc.next();
        switch (r){
            case "y":
                //真正销户
                //从当前账户集合中 删除当前账户对象 销户1就完成了
                if (acc.getMoney()>0){
                    System.out.println("你账户有钱 不允许销户");
                }else{
                accounts.remove(acc);
                System.out.println("你当前销户完成");}

                break;
            default:
                System.out.println(" 你当前账户保留");
        }
    }

    /**
     * 修改密码
     *
     * @param sc 扫描器
     * @param acc 当前登陆账户对象
     *
     */
    private static void updatePassWord(Scanner sc, Account acc) {
        System.out.println("========用户密码修改=========");
        while (true) {
            System.out.println("请你输入当前密码");
            String password=sc.next();
            //判断密码是否正确
            if (acc.getPassWord().equals(password)){
                while (true) {
                    //密码正确
                    //输入新密码
                    System.out.println("请你输入新密码");
                    String newPassword=sc.next();
                    System.out.println("请你确认新密码");
                    String okPassword=sc.next();
                    if (newPassword.equals(okPassword)){
                        //二次密码一致 可以修改
                        acc.setPassWord(okPassword);
                        System.out.println("恭喜你，密码修改成功");
                        return;
                    }else{
                        System.out.println("你输入的二次密码不一致");
                    }
                }
            }else{
                System.out.println("你输入的密码不正确");
            }
        }
    }

    /**
     * 转账
     * @param sc 扫描器
     *
     * @param acc  自己账户对象
     * @param accounts 全部账户集合
     *
     */
    private static void transMoney(Scanner sc, Account acc, ArrayList<Account> accounts) {
        System.out.println("=====转账操作======");
        //1.判断是否足够二个账户
        if (accounts.size()<2){
            System.out.println("当前系统中，不足俩个账户，不能进行转账 请你开户"
            );
            return;
        }
        //2.开始转账 判断自己账户是否有钱
        if (acc.getMoney()==0){
            System.out.println("对不起，你自己都没钱就别转了");
            return;
        }
//         3、真正转账
        while (true) {
            System.out.println("请你输入对方卡号");
            String cardId = sc.next();
            //这个账户不能是自己的卡号
            if (cardId.equals(acc.getCardId())){
                System.out.println("对不起，你不以给自己进行转账");
                continue;
            }

            //判断卡号是否存在 根据卡号去查询对方账
            Account account=getAccountByCardId(cardId,accounts);
            if (account==null){
                System.out.println("对不起，你输入的账户不存在 请重新输入");
            }else{
                //这个账户对象存在。认证姓氏  、
             String userName=   account.getUserName();
             String tip="*"+userName.substring(1);
                System.out.println("请你输入"+tip+"姓氏");
               String preName= sc.next();

               //马上认证姓氏是否输入正确
                if (userName.startsWith(preName)){
                    //认证通过

                    while (true) {
                        System.out.println("请你输入转账金额");
                        double money =  sc.nextDouble();
                        //判断余额是否足够
                        if (money>acc.getMoney()){
                            System.out.println("对不起 余额不足 你最多可以转账"+acc.getMoney());
                        }else{
                            //余额足够可以转
                            acc.setMoney(acc.getMoney()-money);
                            account.setMoney(account.getMoney()+money);
                            System.out.println("转账成功。你的账户剩余"+acc.getMoney());
                            return;
                        }
                    }
                }else{
                    System.out.println("对不起，你输入的信息有误");
                }



            }
        }


    }



    /**
     * 取钱
     * @param acc 当前账户对象
     * @param sc 扫描器
     */
    private static void drawMoney(Account acc, Scanner sc) {
        System.out.println("======用户取钱操作========");
        //1.判断是否足够100元
        if (acc.getMoney()<100){
            System.out.println("对不起，当前账户不够100元，不能取钱");
            return;
        }

        while (true) {
            //2.提示用户输入1金额
            System.out.println("请你输入取钱金额");
            double money=sc.nextDouble();


//        3.判断这个金额是否满足要求
            if (money>acc.getQuotaMoney()){
                System.out.println("对不起，你当前取款金额超过每次限额，每次最多可取" + acc.getQuotaMoney());
            }else{
                //没有超过当次限额
                //判断是否超过账户余额
                if (money>acc.getMoney()){
                    System.out.println("余额不足，你账户总余额是"+acc.getMoney());
                }else{
                    //可以
                    System.out.println("恭喜你取钱"+money+"元成功！");
                    //更新余额
                acc.setMoney(acc.getMoney()-money);
                //取钱结束
                    showAccount(acc);
                    return;

                }

            }
        }

    }

    /**
     * 存钱
     * @param acc 当前账户对象
     * @param sc 扫描器
     */
    private static void depositMone(Account acc, Scanner sc) {
        System.out.println("============ 用户存钱操作======");
        System.out.println("请你输入存款金额");
         double money= sc.nextDouble();

         //更新账户余额 原来的+存入的
        acc.setMoney(acc.getMoney()+money);
        System.out.println("恭喜你存钱成功，当前账户信息如下:");
        showAccount(acc);
    }

    /**
     * 展示账户 信息
     * @param acc
     */
    private static void showAccount(Account acc) {
        System.out.println("========当前账户如下============");
        System.out.println("卡号"+acc.getCardId());
        System.out.println("户主"+acc.getUserName());
        System.out.println("余额"+acc.getMoney());
        System.out.println("限额"+acc.getQuotaMoney());
    }

    /**
     * 用户开户功能的实现
     * @param accounts 接受的账户集合
     */
    private static void register(ArrayList<Account> accounts,Scanner sc) {
        System.out.println("============系统开户操作====================");
        //1.创建一个 账户对象 用于后期封装账户信息
        Account account=new Account();

        //2.录入当前这个账户信息 注入到账户对象中去
            System.out.println("请你输入账户名：");
            String userName=sc.next();
            account.setUserName(userName);

            while (true) {
            System.out.println("请你输入账户密码：");
            String passWord=sc.next();
            System.out.println("请你输入确认密码：");
            String okpassWord=sc.next();
            if (okpassWord.equals(passWord)){
                //密码 认证通过 可以注入给账户对象
                account.setPassWord(okpassWord);
                break;//密码录入成功 死循环没有必要继续
            }else {
                System.out.println("你输入的二次密码不一致 请重新输入 ");
            }
        }
        System.out.println("请你输入账户当次限额：");
        double quotaMoney=sc.nextDouble();
        account.setQuotaMoney(quotaMoney);

        //为账户随机8位且与其他账户 的卡号不重复的号码（独立成方法）
      String cardId = getRandomCardId(accounts);
            account.setCardId(cardId);


//        3.把账户对象添加 集合中去
        accounts.add(account);
        System.out.println("恭喜你"+userName+"先生/女士，你开户成功你的卡号是："+cardId+"请你妥善保管");

    }

    /**
     * 账户生成8位与其他账户卡号不同的方法
     * @return
     */
    private static String getRandomCardId(ArrayList<Account>accounts) {
        Random r= new Random();
        while (true) {
            //1.先生成8位数字
            String cardId="";
            for (int i = 0; i < 8; i++) {
             cardId+=   r.nextInt(10);

            }

            //2.判断 这个8位卡号 是否 与其他账户的卡号 重复
            //根据卡号 去查询账户对象
            Account acc=    getAccountByCardId(cardId,accounts);
            if (acc==null){
                //说明caradid没有重复 这个是新卡号可以使用作为新注册卡号
                return  cardId;

            }
        }

    }

    /**
     * 根据卡号查询出一个账户对象出来
     *
     * @param cardId 卡号
     * @param accounts 全部账户的集合
     * @return 账户对象 null
     */
    private  static Account getAccountByCardId(String cardId,ArrayList<Account>accounts){
        for (int i = 0; i < accounts.size(); i++) {
          Account acc=  accounts.get(i);
          if (acc.getCardId().equals(cardId)){
              return  acc;
          }
        }return  null; //查无此账号
    }
}
